/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package labbd_._projetofinal;

import java.awt.Image;
import java.io.*;
import java.sql.Blob;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleTypes;
import oracle.sql.BLOB;

/**
 *
 * @author bimaoe
 */
public class Oferta {

	private int idproduto;
	private int nrooferta;
	private double valorpromocao;
	private double valororiginal;
	private String descricao;
	private Blob foto;

	public Oferta(){}

	public Oferta(int idproduto, int nrooferta, double valorpromocao,
				double valororiginal, String descricao, Blob foto){
		this.idproduto = idproduto;
		this.nrooferta = nrooferta;
		this.valorpromocao = valorpromocao;
		this.valororiginal = valororiginal;
		this.descricao = descricao;
		this.foto = foto;
	}

	public int getIdProduto () {
		return idproduto;
	}
	public int getNroOferta () {
		return nrooferta;
	}
	public double getValorPromocao () {
		return valorpromocao;
	}
	public double getValorOriginal () {
		return valororiginal;
	}
	public String getDescricao () {
		return descricao;
	}
	public Image getFoto () {
		return getImage(foto);
	}

        public Blob getFotoBlob() {
            return foto;
        }


	/**
	 * Método para criação de uma nova oferta
	 * @param in_conn
	 * @param in_idproduto
	 * @param in_quantidade
	 * @param in_validade
	 * @param in_diasuteis
	 * @param in_horario
	 * @param in_retirada
	 * @param in_nropessoas
	 * @param in_caminho
	 * @throws SQLException
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws Exception
	 */
	public static void novaOferta (OracleConnection in_conn, int in_idproduto,
		int in_quantidade, int in_validade, String in_diasuteis,
		String in_horario, String in_retirada, int in_nropessoas,
		String in_caminho) throws SQLException,
		FileNotFoundException, IOException, Exception {

		in_conn.commit();
		in_conn.setAutoCommit(false);

		String query = "begin pkg_oferta.proc_novaOferta (?,?,?,?,?,?,?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) in_conn.prepareCall(query);
		Ocallstmt.registerOutParameter(1, java.sql.Types.BLOB); //Numero da oferta
		Ocallstmt.setInt (2, in_idproduto);
		Ocallstmt.setInt (3, in_quantidade);
		Ocallstmt.setInt(4, in_validade);
		Ocallstmt.setString(5, in_diasuteis);
		Ocallstmt.setString (6, in_horario);
		Ocallstmt.setString (7, in_retirada);
		Ocallstmt.setInt (8, in_nropessoas);

                System.err.println("Trocando foto");
            try {
                Ocallstmt.execute();
                if (in_caminho == null) { //Passou um caminho pra foto
					in_caminho = "./images/noimage.jpg";
				}
				BLOB fotoBlob = (BLOB) Ocallstmt.getObject(1);
				alteraFoto(fotoBlob , in_caminho);

                Ocallstmt.close();
                in_conn.commit();
            } catch (SQLException ex) {
                    System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
                    in_conn.rollback();
                    throw ex;
            } finally {
                    in_conn.setAutoCommit(true);
            }
            System.err.println ("Oferta Cadastrada");
	}
	/**
	 * Método que altera o a foto de uma oferta no banco de dados
	 * @param foto
	 * @param caminho
	 * @throws SQLException
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws Exception
	 */
	public static void alteraFoto (BLOB foto, String caminho) throws SQLException,
		FileNotFoundException, IOException, Exception {

		try {
			byte[] buffer = new byte[foto.getBufferSize()];
			int read;
			OutputStream os = foto.getBinaryOutputStream();
			FileInputStream fis = new FileInputStream(caminho);

			while((read = fis.read(buffer)) != -1){
					os.write(buffer, 0, read);
					System.err.println("Lendo buffer");
			}

			os.close();
			fis.close();
		} catch (SQLException ex) {
			ex.printStackTrace();
			throw ex;
		} catch (FileNotFoundException ex){
			System.err.println("Exception" + ex.getCause() + ex.getMessage());
		}

	}

	/**
	 *
	 * @param in_conn
	 *	Conexão aberta com o banco de dados Oracle.
	 *	Método não fecha a conexão.
	 * @return
	 *	Lista de ofertas válidas no momento.
	 * @throws SQLException
	 */
	public static ArrayList<Oferta> getOfertasValidas (OracleConnection in_conn)
		throws SQLException {

		ArrayList<Oferta> ret = new ArrayList<Oferta>();
		Image image = null;
		String query = "begin pkg_oferta.proc_getOfertasValidas(?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) in_conn.prepareCall(query);
		Ocallstmt.registerOutParameter(1, OracleTypes.CURSOR);

		System.err.println("Pegando ofertas validas");
		try {
				Ocallstmt.execute();
				ResultSet rs = (ResultSet) Ocallstmt.getObject(1);
				System.out.println ("Ofertas de hoje:");

				while (rs.next()) {
						System.err.println ("ID do produto: "+rs.getInt("IDPRODUTO")+
								" Numero da oferta: "+rs.getInt("NROOFERTA")+
								" Valor original: "+rs.getDouble("VALOR")+
								" Valor promocional: "+rs.getDouble("VALORPROMO"));
						System.err.println ("\tDescricao: "+rs.getString ("DESCRICAO"));

						Blob fotoBlob = rs.getBlob("FOTO");

						System.err.println("Adicionando no array");
						if(!ret.add(new Oferta( rs.getInt("IDPRODUTO"), rs.getInt("NROOFERTA"),
								rs.getDouble("VALORPROMO"), rs.getDouble("VALOR"),
								rs.getString ("DESCRICAO"), fotoBlob) ))
							System.err.println("nao foi possivel adicionar");
				}
				rs.close();
				Ocallstmt.close();
		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
			throw ex;
		}
		if(ret.isEmpty()) System.err.println("Não há ofertas antes do retorno");
		return ret;
	}

	public static Image getImage(Blob foto){
		Image image = null;
		try {
			InputStream is = foto.getBinaryStream();
			image = ImageIO.read(is);

		} catch (IOException ex) {
			System.err.println ("Exception:"+ex.getMessage());
		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
		} finally {
		}

		return image;
	}
	/**
	 *
	 * @param in_conn
	 *	Conexão aberta com o banco de dados Oracle.
	 *	Método não fecha a conexão.
	 * @return
	 *	Verdadeiro: Oferta não está esgotada
	 *	Falso: Oferta esgotada
	 * @throws SQLException
	 */
	public boolean isDisponivel (OracleConnection in_conn) throws SQLException {
		String query = "begin ? := pkg_oferta.func_qtdeDisponivel(?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) in_conn.prepareCall(query);
		Ocallstmt.registerOutParameter(1, java.sql.Types.INTEGER);
		Ocallstmt.setInt (2, idproduto);
		Ocallstmt.setInt (3, nrooferta);

		try {
			Ocallstmt.execute();
			int qtdeDisp = Ocallstmt.getInt(1);
			if (qtdeDisp > 0)	return true;
		} catch (SQLException ex) {
			System.err.println("Exception" + ex.getCause() + ex.getMessage());
			throw ex;
		}
		return false;
	}
}
